package com.broada.apm.topo;

import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.broada.apm.model.ApplicationSystem;
import com.broada.apm.model.Service;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
//import com.google.gson.annotations.Expose;

public class TApp implements Serializable, Apdexable {
	private static final long serialVersionUID = 1L;
	private String id;
//	@Expose(serialize=false)
	private Map<String, TAppService> services = Maps.newHashMap();
//	@Expose(serialize=false)
	private Map<String, TAppResource> keyResources = Maps.newHashMap();
//	@Expose(serialize=false)
	private Map<String, TAppResource> resources = Maps.newHashMap();
//	@Expose(serialize=false)
	private Map<String, TAppRelation> relations = Maps.newHashMap();
//	@Expose(serialize=false)
	private Map<String,TAppService> keyServices = Maps.newHashMap();
	private ApplicationSystem application;
	private long apdexT;
	private Map<String, String> clusterTransaction = Maps.newHashMap();
	
	public TApp(ApplicationSystem application, String id) {
		this.application = application;
		this.id = id;
		updateApdexT();
	}

	public void addClusterTransaction(String transaction, String tranId) {
		clusterTransaction.put(transaction, tranId);
	}
	
	public Map<String, String> getClusterTransaction() {
		return clusterTransaction;
	}
	
	public String getClusterTransactionId(String transaction) {
		return clusterTransaction.get(transaction);
	}
	
	public void addService(TAppService service) {
		services.put(service.getId(), service);
	}

	public Collection<TAppService> getServices() {
		return Lists.newArrayList(services.values());
	}

	public TAppService getService(String id) {
		return services.get(id);
	}

	public void addResource(TAppResource resource) {
		resources.put(resource.getId(), resource);
	}

	public Collection<TAppResource> getResources() {
		return resources.values();
	}

	public TAppResource getResource(String id) {
		return resources.get(id);
	}
	
	public void addKeyService(TAppService keyService) {
		keyServices.put(keyService.getId(), keyService);
	}
	
	public void addKeyResource(TAppResource resource) {
		keyResources.put(resource.getId(), resource);
	}

	public Collection<TAppResource> getKeyResources() {
		return Lists.newArrayList(keyResources.values());
	}

	public TAppResource getKeyResource(String id) {
		return keyResources.get(id);
	}
	public Collection<TAppRelation> getRelations() {
		return Lists.newArrayList(relations.values());
	}
	public void addRelation(TAppRelation relation){
		relations.put(relation.getId(), relation);
	}
	
	public boolean isKeyService(TAppService service) {
		return keyServices.containsKey(service.getId());
	}
	public Set<String> getKeyServiceIds() {
		return keyServices.keySet();
	}
	
	public String getId() {
		return id;
	}

	public ApplicationSystem getApplication() {
		return application;
	}
	
	public String toSimpleString() {
		return "TApp [id=" + id +"]"; 
	}
	
	public String toDebugString() {
		return "TApp [id=" + id + ", services=" + services + ", keyResources=" + keyResources
				+ ", resources=" + resources + ", application=" + application + ", keyService=" + keyServices + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		TApp other = (TApp) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		if (getKeyServiceId() == null) {
			if (other.getKeyServiceId() != null)
				return false;
		} else if (!getKeyServiceId().equals(other.getKeyServiceId()))
			return false;
		if(getServices().size() != other.getServices().size())
			return false;
		for(TAppService service : getServices()) {//集群节点发生变化也认为app不相等
			if(service.getService().getNodeType() == Service.NodeTypeCluster) {
				TAppService ser = other.getService(service.getService().getId());
				if(ser != null && service.getService().getNodeIds() != null && ser.getService().getNodeIds() != null && 
						service.getService().getNodeIds().length != ser.getService().getNodeIds().length) {
					return false;
				}
			}
		}
		return true;
	}

	/**
	 * 关键节点是集群节点，则返回集群节点的ID
	 * 
	 * @Title: getKeyServiceId
	 * @Description:
	 * @param @return
	 * @return String
	 * @throws
	 */
	public String getKeyServiceId() {
		String keyServiceId = null;
		for (Entry<String, TAppService> entry : keyServices.entrySet()) {
			if (entry.getValue() != null && entry.getValue().getCluster() != null)
				keyServiceId = entry.getValue().getCluster().getId();
			else
				keyServiceId = entry.getKey();
			break;
		}
		return keyServiceId;
	}
	
	public long getApdexT() {
	    return apdexT;
	}
	private void updateApdexT() {
        if (application != null) {
            if (application.getApdex_t() > 0) {
                apdexT = (long) (application.getApdex_t() * 1000 * 1000);
            }
        } else {
            apdexT = DEFAULT_SATISFACTION_THRESHOLD;
        }
	}
	
}
